/**
 ******************************************************************************
 * @file app_boot.c
 * @author GX (2524913364@qq.com)
 * @brief 开机动画的应用，使用到自己封装的 "lcd.h" 和 "fonts.h"(包含在"lcd.h"中)
 *        1.可见区轮换——提高画面刷新时的流畅度
 *        2.不匀速进度条
 *        3.皮卡丘奔跑动画进度条
 *        4.颜色渐变字体——类似呼吸灯
 * @version 1.0.1
 * @date 2022-07-10
 * 
 * @copyright Copyright (c) 2022
 * 
 ******************************************************************************
 *----------------------------------------------------------------------------*
 *  Remark         : Description                                              *
 *----------------------------------------------------------------------------*
 *  Change History :                                                          *
 *  <Date>     | <Version> | <Author>       | <Description>                   *
 *----------------------------------------------------------------------------*
 *  2022-07-10 | 1.0.0     | GX             | Create file                     *
 *----------------------------------------------------------------------------*
 *  2022-07-14 | 1.0.1     | GX             | The change effect of font color *
 *             |           |                | gradient is better.             *
 *----------------------------------------------------------------------------*                                                                           *
 ******************************************************************************
 */


/*----------------------------- start of file -------------------------------*/

#include "app_boot.h"
#include "lcd.h"


/*******************************************************************************
 * 
 *                               开机动画相关函数
 * 
*******************************************************************************/

/**
 * @brief 开机动画函数
 * 
 * @return true   
 * @return false 
 */
bool play_boot_animation(void)
{
  /*------------------------------开启显示屏幕-----------------------------*/
  int fd_lcd;                             /* 打开文件获取文件描述 */
  int *fb_base = NULL;                    /* 映射后显存的地址 */
  struct fb_var_screeninfo vinfo;         /* 显卡设备的可变属性结构体 */
	/* 打开文件 */
	fd_lcd = open(LCD_PATH, O_RDWR);
	if(fd_lcd == -1)
	{
		perror("open lcd");
    return false;
	}
  else
	{
		/* 显存映射 */
		fb_base = mmap(NULL, LCD_BUFF_SIZE*LCD_BLOCK,  PROT_READ|PROT_WRITE,
					MAP_SHARED, fd_lcd, 0);
		if(fb_base == MAP_FAILED) 
		{
			perror("申请显存失败");
      close(fd_lcd);
      return false;
		} 
    
    if(ioctl(fd_lcd, FBIOGET_VSCREENINFO, &vinfo) != 0)/* 获取可变属性 */
    {
        perror("获取LCD设备可变属性信息失败");
        return false;
    }
  }


  // printf("in\n");
  /*----------------------------- 开始显示动画 ---------------------------------*/
  
  /* 显示字符相关配置------------------------------- */
  /* 要先把进来前的字体配置记住，在结束后要设置回来 */
  bool color_add = true;  /* 为真时字体颜色递增，假时递减 */
  bool useBack;
  u_int32_t TextColor, BackColor;
  sFONT *fonts;
  /* Font48x64 在"fonts.h"中，一般"lcd.h"已包含 */
  sFONT boot_fonts = Font32x48;                   /* 本模块要使用的字体大小 */
  u_int32_t boot_TextColor = BOOT_TEXT_COLOR_MIN; /* 本模块要使用的字体颜色 */
  fonts = LCD_GetFont();
  LCD_GetColors(&TextColor, &BackColor, &useBack);
  LCD_SetFont(&boot_fonts); 
  LCD_SetColors(boot_TextColor, BOOT_PROGRESS_BAR_COLOR, false);

  /* 显示皮卡丘和进度条相关配置----------------------- */
  int bar_length = 0;     /* 进度条当前长度 */
  int dis_bar_length = 0; /* 实际显示在屏幕上的进度条长度 */
  int delta_length = 0;   /* 进度条增量 */ 
  int pikachu = 1;        /* 显示第几个皮卡丘 */
  char pika_path_buf[50];
  srand((int)time(NULL)); /* 设置随机数种子，让进度条增长速度变化 */

  /* 开始显示-------------------------------------- */
  /* 在三个区都提前画上壁纸，后面就不用再画了 */
  lcd_show_bmp(LCD_DISPLAY(fb_base, 0), BOOT_WALLPAPER_PATH, 0, 0);
  lcd_show_bmp(LCD_DISPLAY(fb_base, 1), BOOT_WALLPAPER_PATH, 0, 0);
  lcd_show_bmp(LCD_DISPLAY(fb_base, 2), BOOT_WALLPAPER_PATH, 0, 0);

  /* 显示第一只皮卡丘 */  
  sprintf(pika_path_buf, "%s%d.bmp", BOOT_ANIMATION_PATH, pikachu);
  lcd_show_bmp(LCD_DISPLAY(fb_base, ++view_block), pika_path_buf, 
                dis_bar_length,  BOOT_PROGRESS_BAR_Y);
  LCD_SET_DISPLAY(fd_lcd, &vinfo, view_block); 

  while( bar_length <= BOOT_PROGRESS_BAR_LENGTH )
  {
    /* 更新进度条长度 */
    delta_length = (int)(rand()%35+1);
    /* 这里设置一些值，增量等于某些值的时候进度条不累加，只是为了模拟卡顿的情况 */
    if((delta_length!=5)||(delta_length!=8)||(delta_length!=16)||(delta_length!=20)
      ||(delta_length!=6)||(delta_length!=17)||(delta_length!=23)||(delta_length!=32)
      ||(delta_length!=3)||(delta_length!=30)||(delta_length!=11))
    {
      bar_length += delta_length;
    }

    dis_bar_length = bar_length;
    dis_bar_length = (dis_bar_length > BOOT_PROGRESS_BAR_LENGTH) ?
                      BOOT_PROGRESS_BAR_LENGTH : dis_bar_length;
    view_block++;
    /* 绘制字符 */
    LCD_SetColors(boot_TextColor, BOOT_PROGRESS_BAR_COLOR, false);                  
    if(dis_bar_length < BOOT_PROGRESS_BAR_LENGTH)
    {
      DispStringLine_EN(LCD_DISPLAY(fb_base, view_block), 7, 7, BOOT_TEXT_LOADING);
    }
    else
    {
      lcd_show_bmp(LCD_DISPLAY(fb_base, view_block), BOOT_WALLPAPER_PATH, 0, 0);
      DispStringLine_EN(LCD_DISPLAY(fb_base, view_block), 7, 9, BOOT_TEXT_FINISH);
    }
    /* 绘制进度条 */
    lcd_rectangle(LCD_DISPLAY(fb_base, view_block), 
                  BOOT_PROGRESS_BAR_X, BOOT_PROGRESS_BAR_Y,
                  dis_bar_length, BOOT_PROGRESS_BAR_HEIGHT, 
                  BOOT_PROGRESS_BAR_COLOR);
    /* 绘制皮卡丘 */
    lcd_show_bmp(LCD_DISPLAY(fb_base, view_block), pika_path_buf, 
                  dis_bar_length,  BOOT_PROGRESS_BAR_Y);


    LCD_SET_DISPLAY(fd_lcd, &vinfo, view_block); 

    pikachu++;
    pikachu = (pikachu > BOOT_PIKA_NUM) ? 1 : pikachu;


    if ( color_add )  /* "change text color" */
    {
      boot_TextColor += BOOT_TEXT_COLOR_ADD;
      if( boot_TextColor > BOOT_TEXT_COLOR_MAX )
      {
        boot_TextColor = BOOT_TEXT_COLOR_MAX;
        color_add = false;  /* 开始递减 */
      }
    }
    else
    {
      boot_TextColor -= BOOT_TEXT_COLOR_ADD;
      if( boot_TextColor < BOOT_TEXT_COLOR_MIN )
      {
        boot_TextColor = BOOT_TEXT_COLOR_MIN;
        color_add = true;  /* 开始递减 */
      }
    }
    /* "change text color"   end */   

    /* 切换皮卡丘图片 */
    sprintf(pika_path_buf, "%s%d.bmp", BOOT_ANIMATION_PATH, pikachu);

    usleep(70000);
  }
  /* while(1) end--------------------------------------------------------- */


  /* 恢复字体设置 */
  LCD_SetFont(fonts); 
  LCD_SetColors(TextColor, BackColor, useBack);

  view_block = 0;
  // printf("ok\n");
  munmap(fb_base, LCD_BUFF_SIZE*LCD_BLOCK);
  close(fd_lcd);

  usleep(800000);

  return true;
}

 

/*------------------------------ end of file --------------------------------*/

